package gapidt.plugin.views;

import gapidt.analysis.APIDesignAnalysisResult;
import gapidt.analysis.DesignProblem;
import gapidt.common.Locale;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

public class AnalysisResultsLabelProvider extends StyledCellLabelProvider implements ILabelProvider {
	
	private Map<ImageDescriptor, Image> imageCache = new HashMap<ImageDescriptor, Image>();
	
	@SuppressWarnings("unchecked")
	public String getText(Object element){
		if(element instanceof APIDesignAnalysisResult && ((APIDesignAnalysisResult<?>) element).getSubject() instanceof IJavaElement){
			return ((APIDesignAnalysisResult<IJavaElement>) element).getSubject().getElementName();
		}else if(element instanceof DesignProblem)
			return ((DesignProblem<?>) element).getName();
		return element.toString();
	}
	
	public String getCommentText(Object element){
		if(element instanceof APIDesignAnalysisResult && ((APIDesignAnalysisResult<?>) element).getSubject() instanceof IJavaElement){
			String designProblemsCount = Locale.getMessage("no_design_problems_found");
			if(((APIDesignAnalysisResult<?>) element).getDesignProblemsCount() > 0){
				int count = ((APIDesignAnalysisResult<?>) element).getDesignProblemsCount();
				designProblemsCount = count+" "+Locale.getMessage(count>1?"design_problems":"design_problem");
			}
			return " ("+designProblemsCount+")";
		}
		return "";
	}
	
	@Override
	public String getToolTipText(Object element) {
		if(element instanceof DesignProblem){
			DesignProblem<?> designProblem = (DesignProblem<?>) element;
			String tooltip = "";
			tooltip += Locale.getMessage("problem")+": "+designProblem.getProblemDescription()+"\n";
			tooltip += Locale.getMessage("solution")+": "+designProblem.getSolutionDescription();
			return tooltip;
		}
		return null;
	}
	
	public Point getToolTipShift(Object object) {
		return new Point(5,5);
	}
	
	public int getToolTipDisplayDelayTime(Object object) {
		return 0;
	}
	
	public int getToolTipTimeDisplayed(Object object) {
		return -1;
	}
	
	public Image getImage(Object element) {
		ImageDescriptor descriptor = null;
		if(element instanceof APIDesignAnalysisResult && ((APIDesignAnalysisResult<?>)element).getSubject() instanceof IPackageFragmentRoot){
			descriptor = JavaUI.getSharedImages().getImageDescriptor(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PACKFRAG_ROOT);
		}else if(element instanceof APIDesignAnalysisResult && ((APIDesignAnalysisResult<?>)element).getSubject() instanceof IPackageFragment){
			descriptor = JavaUI.getSharedImages().getImageDescriptor(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PACKAGE);
		}else if(element instanceof APIDesignAnalysisResult && ((APIDesignAnalysisResult<?>)element).getSubject() instanceof ICompilationUnit){
			descriptor = JavaUI.getSharedImages().getImageDescriptor(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_CUNIT);
		}else if(element instanceof APIDesignAnalysisResult && ((APIDesignAnalysisResult<?>)element).getSubject() instanceof IType){
			descriptor = JavaUI.getSharedImages().getImageDescriptor(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_CLASS);
		}else if(element instanceof APIDesignAnalysisResult && ((APIDesignAnalysisResult<?>)element).getSubject() instanceof IMethod){
			descriptor = JavaUI.getSharedImages().getImageDescriptor(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PUBLIC);
		}else if(element instanceof DesignProblem){
			descriptor = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_WARN_TSK);
		}
		if(descriptor != null){
		   //obtain the cached image corresponding to the descriptor
		   Image image = (Image) imageCache.get(descriptor);
		   if (image == null) {
		       image = descriptor.createImage();
		       imageCache.put(descriptor, image);
		   }
		   return image;
		}
		return null;
	}
	
	public void dispose(){
	   for (Iterator<Image> i = imageCache.values().iterator(); i.hasNext();) {
	       ((Image) i.next()).dispose();
	   }
	   imageCache.clear();
	}

	@Override
	public void update(ViewerCell cell) {
		
		StyledString styledString = new StyledString(getText(cell.getElement()));

		String commentText = getCommentText(cell.getElement());
		if(!commentText.isEmpty())
			styledString.append(commentText, StyledString.QUALIFIER_STYLER);

        cell.setText(styledString.toString());
        cell.setStyleRanges(styledString.getStyleRanges());
        cell.setImage(getImage(cell.getElement()));
		super.update(cell);
	}
}
